package br.com.afi.pattern.business;

import java.io.Serializable;
import java.util.List;

import br.com.afi.pattern.converter.Converter;
import br.com.afi.pattern.model.Model;
import br.com.afi.pattern.vo.ValueObject;
import br.com.afi.pattern.wrapper.Wrapper;
import br.com.afi.pattern.wrapper.WrapperList;

/**
 * Essa interface possui as assinaturas dos métodos necessários para implementar as quatro operações
 * básicas. Porém todos os métodos retornam e recebem um tipo Wrapper, onde o objeto pode facilmente
 * ser obtido como {@link ValueObject} ou {@link Model}. Implemente esta interface nas classes que
 * contém a regra de negócio.
 * 
 * @author André de Fontana Ignacio
 * @version 1.0
 * @param <E> Tipo do Model (Entity)
 * @param <ID> Tipo do Id do Model (Entity)
 * @param <V> Tipo do Value Object
 */
public interface BusinessWrapper<E extends Model<ID>, ID extends Serializable, V extends ValueObject>
{
	/**
	 * Atribui o conversor entre ValueObject e o Model (Entity)
	 * 
	 * @param converter Conversor
	 */
	public void setConverter( Converter<E, V> converter );

	/**
	 * Cria um Wrapper apartir do Model informado.
	 * 
	 * @param m Model (Entity)
	 * @return Wrapper
	 */
	public Wrapper<E, V> createWrapper( E m );

	/**
	 * Cria um Wrapper apartir do Value Object informado.
	 * 
	 * @param v Value Object
	 * @return Wrapper
	 */
	public Wrapper<E, V> createWrapper( V v );

	/**
	 * Cria uma Lista Wrappers apartir de uma lista de Models.
	 * 
	 * @param ms Lista de Models (Entity)
	 * @return Lista de Wrappers
	 */
	public WrapperList<E, V> createWrapperListFromModel( List<E> ms );

	/**
	 * Cria uma Lista Wrappers apartir de uma lista de Value Objects.
	 * 
	 * @param vos Lista de Value Objects
	 * @return Lista de Wrappers
	 */
	public WrapperList<E, V> createWrapperListFromVO( List<V> vos );

	/**
	 * Busca através do Id.
	 * 
	 * @param id Id
	 * @return Wrapper
	 */
	public Wrapper<E, V> findById( ID id );

	/**
	 * Verifica se existe um registro com o Id informado.
	 * 
	 * @param id Id
	 * @return Verdadeiro se existir
	 */
	public boolean existsById( ID id );

	/**
	 * Solicita a gravação dos dados do {@link Wrapper} informado.
	 * 
	 * @param w Wrapper
	 * @return Wrapper
	 * @throws BusinessException Lançada quando ocorrer alguma exceção na regra de negócio
	 */
	public Wrapper<E, V> save( Wrapper<E, V> w ) throws BusinessException;

	/**
	 * Solicita a remoção dos dados do {@link Wrapper} informado.
	 * 
	 * @param w Wrapper
	 * @throws BusinessException Lançada quando ocorrer alguma exceção na regra de negócio
	 */
	public void delete( Wrapper<E, V> w ) throws BusinessException;;

	/**
	 * Busca todos os registros.
	 * 
	 * @return Lista de Wrappers
	 */
	public WrapperList<E, V> findAll();

	/**
	 * Busca os registros através do exemplo informado.
	 * 
	 * @param example Wrapper de Exemplo
	 * @param excludeProperty Propriedades que não seram utilizadas na busca
	 * @return Lista de Wrappers
	 */
	public WrapperList<E, V> findByExample( Wrapper<E, V> example, String... excludeProperty );

	/**
	 * Busca os registros através do example informado utilizando insensitive like.
	 * 
	 * @param example Wrapper de Exemplo
	 * @param includeRelationships Incluir relacionamentos?
	 * @param excludeProperty Propriedades que não seram utilizadas na busca
	 * @return Lista de Wrappers
	 */
	public WrapperList<E, V> findByExampleILike( Wrapper<E, V> example, boolean includeRelationships, String... excludeProperty );
}
